context("coord_sf")

test_that("basic plot builds without error", {
  skip_if_not_installed("sf")

  nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
  plot <- ggplot(nc) +
    geom_sf() +
    coord_sf()

  # Perform minimal test as long as vdiffr test is disabled
  expect_error(regexp = NA, ggplot_build(plot))

  skip("sf tests are currently unstable")
  expect_doppelganger("sf-polygons", plot)
})

test_that("graticule lines can be removed via theme", {
  skip_if_not_installed("sf")

  df <- data_frame(x = c(1, 2, 3), y = c(1, 2, 3))
  plot <- ggplot(df, aes(x, y)) +
    geom_point() +
    coord_sf() +
    theme_gray() + # to test for presence of background grob
    theme(panel.grid = element_blank())

  expect_doppelganger("no panel grid", plot)
})

test_that("axis labels can be set manually", {
  skip_if_not_installed("sf")

  plot <- ggplot(sf::st_polygon(list(matrix(1e3*c(1, 2, 3, 1, 1, 3, 2, 1), ncol = 2)))) +
    geom_sf()

  # autogenerated labels
  b <- ggplot_build(
    plot +
      scale_x_continuous(breaks = c(1000, 2000, 3000)) +
      scale_y_continuous(breaks = c(1000, 1500, 2000))
  )
  graticule <- b$layout$panel_params[[1]]$graticule
  expect_identical(
    graticule[graticule$type == "E", ]$degree_label,
    c("1000", "2000", "3000")
  )
  expect_identical(
    graticule[graticule$type == "N", ]$degree_label,
    c("1000", "1500", "2000")
  )

  # character labels
  b <- ggplot_build(
    plot +
      scale_x_continuous(
        breaks = c(1000, 2000, 3000),
        labels = c("A", "B", "C")
      ) +
      scale_y_continuous(
        breaks = c(1000, 1500, 2000),
        labels = c("D", "E", "F")
      )
  )
  graticule <- b$layout$panel_params[[1]]$graticule
  expect_identical(
    graticule[graticule$type == "E", ]$degree_label,
    c("A", "B", "C")
  )
  expect_identical(
    graticule[graticule$type == "N", ]$degree_label,
    c("D", "E", "F")
  )

  # factors are treated like character labels
  # and are not parsed
  b <- ggplot_build(
    plot +
      scale_x_continuous(
        breaks = c(1000, 2000, 3000),
        labels = factor(c("A", "B", "C"))
      ) +
      scale_y_continuous(
        breaks = c(1000, 1500, 2000),
        labels = factor(c("1 * degree * N", "1.5 * degree * N", "2 * degree * N"))
      )
  )
  graticule <- b$layout$panel_params[[1]]$graticule
  expect_identical(
    graticule[graticule$type == "E", ]$degree_label,
    c("A", "B", "C")
  )
  expect_identical(
    graticule[graticule$type == "N", ]$degree_label,
    c("1 * degree * N", "1.5 * degree * N", "2 * degree * N")
  )


  # expressions mixed with character labels
  b <- ggplot_build(
    plot +
      scale_x_continuous(
        breaks = c(1000, 2000, 3000),
        labels = c("A", "B", "C")
      ) +
      scale_y_continuous(
        breaks = c(1000, 1500, 2000),
        labels = parse(text = c("10^3", "1.5 %*% 10^3", "2 %*% 10^3"))
      )
  )
  graticule <- b$layout$panel_params[[1]]$graticule
  expect_identical(
    graticule[graticule$type == "E", ]$degree_label,
    as.list(c("A", "B", "C"))
  )
  parsed <- vector("list", 3)
  parsed[1:3] <- parse(text = c("10^3", "1.5 %*% 10^3", "2 %*% 10^3"))
  expect_identical(
    graticule[graticule$type == "N", ]$degree_label,
    parsed
  )

  # reverse x and y from previous test
  b <- ggplot_build(
    plot +
      scale_y_continuous(
        breaks = c(1000, 2000, 3000),
        labels = c("A", "B", "C")
      ) +
      scale_x_continuous(
        breaks = c(1000, 1500, 2000),
        labels = parse(text = c("10^3", "1.5 %*% 10^3", "2 %*% 10^3"))
      )
  )
  graticule <- b$layout$panel_params[[1]]$graticule
  expect_identical(
    graticule[graticule$type == "N", ]$degree_label,
    as.list(c("A", "B", "C"))
  )
  parsed <- vector("list", 3)
  parsed[1:3] <- parse(text = c("10^3", "1.5 %*% 10^3", "2 %*% 10^3"))
  expect_identical(
    graticule[graticule$type == "E", ]$degree_label,
    parsed
  )

  # autoparsing of degree labels
  data <- sf::st_sfc(
    sf::st_polygon(list(matrix(1e1*c(1, 2, 3, 1, 1, 3, 2, 1), ncol = 2))),
    crs = 4326 # basic long-lat crs
  )

  plot <- ggplot(data) + geom_sf()

  b <- ggplot_build(
    plot +
      scale_x_continuous(breaks = c(10, 20, 30)) +
      scale_y_continuous(breaks = c(10, 15, 20))
  )
  graticule <- b$layout$panel_params[[1]]$graticule
  parsed <- vector("list", 3)
  parsed[1:3] <- parse(text = c("10*degree*E", "20*degree*E", "30*degree*E"))
  expect_identical(
    graticule[graticule$type == "E", ]$degree_label,
    parsed
  )
  parsed[1:3] <- parse(text = c("10*degree*N", "15*degree*N", "20*degree*N"))
  expect_identical(
    graticule[graticule$type == "N", ]$degree_label,
    parsed
  )

})

test_that("Inf is squished to range", {
  skip_if_not_installed("sf")

  d <- cdata(
    ggplot(sf::st_point(c(0, 0))) +
      geom_sf() +
      annotate("text", -Inf, Inf, label = "Top-left")
  )

  expect_equal(d[[2]]$x, 0)
  expect_equal(d[[2]]$y, 1)
})
